SQL 中的笛卡尔积爆炸💥
 · 阅读需 4 分钟
笛卡尔积
首先,要了解笛卡尔积爆炸就得先了解什么是笛卡尔积
笛卡尔积就是把一个表中的每条数据都和另一个表中的每条数据组合,形成一个新的表
y
↑
|    (a1,b3)    (a2,b3)    (a3,b3)
|    ●──────────●──────────●
|    |          |          |
|    |          |          |
|    |          |          |
|    ●──────────●──────────●
|    (a1,b2)    (a2,b2)    (a3,b2)
|    |          |          |
|    |          |          |
|    |          |          |
|    ●──────────●──────────●
|    (a1,b1)    (a2,b1)    (a3,b1)
+──────────────────────────────────→ x
好了现在你知道笛卡尔积了,来写个 800 多行的多表查询吧( bush
sql 中实现笛卡尔积
如果想在 SQL 中实现笛卡尔积,其实很简单
使用 INNER JOIN 就可以把两张表联合起来
SELECT *
FROM A
INNER JOIN B
这是最简单的方式,不加任何的连接条件。但一般进行多表查询肯定不会是单纯的连接起来,一定会有几个连接条件来查询想要的数据
SELECT *
FROM A
INNER JOIN B
ON A.NAME = B.NAME
WHERE .....
笛卡尔积爆炸
名字已经显而易见了,所谓笛卡尔积爆炸就是多个表连接时产生了巨量的数据,导致数据“撑爆”内存,降低查询效率甚至引起服务器宕机
怎么产生的
都是网上摘抄总结的,欢迎补充
- 
多表查询时,缺少连接条件
-- 错误写法:缺少ON条件,产生笛卡尔积
SELECT * FROM table1 JOIN table2;
-- 等价于
SELECT * FROM table1, table2; - 
连接条件不完整
当多表连接时,缺少部分表的连接条件:
-- 三表连接但只指定了两个表的条件
SELECT *
FROM A
JOIN B ON A.id = B.a_id
JOIN C; -- 缺少与A或B的连接条件 - 
多对多关系处理不当
当两个表之间存在多对多关系且中间表连接条件不完整时:
-- 假设A和C是多对多关系,通过B作为关联表
SELECT *
FROM A
JOIN B ON A.id = B.a_id -- 正确
JOIN C ON B.c_id = C.id -- 正确
JOIN D; -- 忘记连接D的条件 
如何解决
- 
始终明确指定连接条件
SELECT \* FROM table1 JOIN table2 ON table1.id = table2.t1_id - 
使用显式 JOIN 语法
- 
优先使用 INNER JOIN/LEFT JOIN 等明确语法
 - 
避免使用隐式连接(逗号分隔)
 
 - 
 - 
检查多表连接
- 
确保每个额外连接的表都有明确的连接条件
 - 
使用表别名提高可读性
 
 - 
 - 
使用 EXISTS 代替 JOIN
当只需要检查存在性时:
SELECT \* FROM A
WHERE EXISTS (SELECT 1 FROM B WHERE B.a_id = A.id) - 
限制结果集大小
SELECT \* FROM table1 JOIN table2 ON ... LIMIT 1000 
总结
本文只是我对于笛卡尔积爆炸的初步了解,目前还没有遇到过,也没有实际解决的经验,属于是纸上谈兵了,祝看到这里的网友遇不到笛卡尔积爆炸 😎
